home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / shells / guest-0.000 / guest-0 / guest-0.2 / parse.c < prev    next >
C/C++ Source or Header  |  1995-05-08  |  7KB  |  265 lines

  1. /*
  2. Parses menu file into a linked list
  3. Copyright (C) 1995  Brian Cully
  4.  
  5. This program is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free Software
  7. Foundation; either version 2 of the License, or (at your option) any later
  8. version.
  9.  
  10. This program is distributed in the hope that it will be useful, but WITHOUT
  11. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  13. details.
  14.  
  15. You should have received a copy of the GNU General Public License along with
  16. this program; if not, write to the Free Software Foundation, Inc., 675 Mass
  17. Ave, Cambridge, MA 02139, USA.
  18.  
  19. please send patches or advice to: `shmit@meathook.intac.com'
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24.  
  25. #include "string.h"
  26. #include "parse.h"
  27.  
  28. static void error(char *message, int lineno) {
  29.    fprintf(stderr, "%i: %s", lineno, message);
  30.    exit(1);
  31. }
  32.  
  33. static void alloc_items(struct menu_items **data, const char *line, int i) {
  34.    int worddex;
  35.    char *word = (char *)malloc(255);
  36.    char errmess[255];
  37.  
  38.    /* Skip white space */
  39.    line += strwhite(line);
  40.            
  41.    if ((worddex = substr(line,word,':')) == -1)
  42.       error("Premature end-of-line\n", i);
  43.  
  44.    /* Advance past word */
  45.    line += worddex+1;
  46.            
  47.    /* Scan for tokens, then dissemate information */
  48.    if (!strcmp(word, MENU_OP_TITLE)) {
  49.       if (substr(line,word,':') == -1)
  50.      error("Premature end-of-line\n",i);
  51.       
  52.       (*data)->type = MENU_TITLE;
  53.       (*data)->name = (char *)malloc(strlen(word)+1);
  54.       strcpy((*data)->name, word);
  55.       (*data)->args = NULL;
  56.           
  57.    } else if (!strcmp(word, MENU_OP_SUB)) {
  58.       if ((worddex = substr(line,word,':')) == -1)
  59.      error("Premature end-of-line\n",i);
  60.       line += worddex + 1;
  61.  
  62.       (*data)->type = MENU_SUB;
  63.       (*data)->name = (char *)malloc(strlen(word)+1);
  64.       strcpy((*data)->name, word);
  65.  
  66.       if (substr(line,word,':') == -1)
  67.      error("Premature end-of-line\n",i);
  68.  
  69.       (*data)->args = (char *)malloc(strlen(word) + 1);
  70.       strcpy((*data)->args, word);
  71.  
  72.    } else if (!strcmp(word, MENU_OP_NOP)) {
  73.       if (substr(line,word,':') == -1)
  74.          error("Premature end-of-line\n", i);
  75.  
  76.       (*data)->type = MENU_NOP;
  77.       (*data)->name = (char *)malloc(strlen(word)+1);
  78.       strcpy((*data)->name, word);
  79.       (*data)->args = NULL;
  80.  
  81.    } else if (!strcmp(word, MENU_OP_EXEC)) {
  82.       if ((worddex = substr(line,word,':')) == -1)
  83.      error("Premature end-of-line\n",i);
  84.       line += worddex + 1;
  85.  
  86.       (*data)->type = MENU_EXEC;
  87.       (*data)->name = (char *)malloc(strlen(word)+1);
  88.       strcpy((*data)->name, word);
  89.  
  90.       if (substr(line,word,':') == -1)
  91.      error("Premature end-of-line\n",i);
  92.  
  93.       (*data)->args = (char *)malloc(strlen(word) + 1);
  94.       strcpy((*data)->args, word);
  95.  
  96.    } else if (!strcmp(word, MENU_OP_EXIT)) {
  97.       if (substr(line,word,':') == -1)
  98.      error("Premature end-of-line\n",i);
  99.  
  100.       (*data)->type = MENU_EXIT;
  101.       (*data)->name = (char *)malloc(strlen(word)+1);
  102.       strcpy((*data)->name, word);
  103.       (*data)->args = NULL;
  104.  
  105.    } else {
  106.       sprintf(errmess, "Unknown token `%s'\n", word);
  107.       error(errmess, i);
  108.    }
  109.  
  110.    /* Allocate another link */
  111.    (*data)->next = (struct menu_items*)malloc(sizeof(struct menu_items));
  112.    (*data)->next->prev = *data;
  113.    *data = (*data)->next;
  114.    (*data)->next = NULL;
  115.  
  116.    free(word);
  117. }
  118.  
  119. /* Parses the file into a linked menu list
  120. ** On entry:
  121. **    menuptr == empty pointer to list
  122. **    menufile == loaded menu file
  123. ** On exit:
  124. **    menuptr == full menu, in linked list
  125. **    returns -1 on error, 0 otherwise
  126. */
  127.  
  128. int parsefile(struct menu **menuptr,char *menufile) {
  129.    char *line, *word;
  130.    int index,i=0;
  131.  
  132.    line = (char *)malloc(255);
  133.    word = (char *)malloc(255);
  134.    *menuptr = (struct menu *)malloc(sizeof(struct menu));
  135.    (*menuptr)->prev = NULL;
  136.    (*menuptr)->next = NULL;
  137.    (*menuptr)->data = NULL;
  138.  
  139.    while ((index = substr(menufile,line,CR)) != -1) {
  140.       int worddex, menu_close;
  141.       
  142.       i++;
  143.       menufile += index+1;
  144.       /* Should probably put a '#' -> '\0' replacement in here */
  145.  
  146.       if ((worddex = substr(line, word, ' ')) == 0) {
  147.      fprintf(stderr, "%i: premature end-of-line\n", i);
  148.      return(-1);
  149.       }
  150.       
  151.       line += worddex + 1;
  152.  
  153.       if (!strcmp(word,MENU_BEGIN)) {
  154.      if (substr(line, word, ' ') == 0) {
  155.         fprintf(stderr, "%i: premature end-of-line\n", i);
  156.         return(-1);
  157.      }
  158.  
  159.      /* Store menu name, for easy retrieval */
  160.      (*menuptr)->name = (char *)malloc(strlen(word)+1);
  161.      strcpy((*menuptr)->name, word);
  162.  
  163.      /* Loop through, defining menu, quit at MENU_END */
  164.      (*menuptr)->data = (struct menu_items *)malloc(sizeof(struct menu_items));
  165.      (*menuptr)->data->next = NULL;
  166.      (*menuptr)->data->prev = NULL;
  167.  
  168.      menu_close = 0;
  169.      while (!menu_close) {
  170.  
  171.         /* Error on EOF, it doesnt belong here */
  172.         if ((index = substr(menufile,line,CR)) == -1)
  173.            error("Premature end-of-file\n", i);
  174.         /* Advance past line */
  175.         menufile += index+1;
  176.         i++;
  177.  
  178.         /* Close menu on MENU_END, otherwise define node */
  179.         if (!strcmp(line,MENU_END)) {
  180.            menu_close = 1;
  181.         } else {
  182.            alloc_items(&((*menuptr)->data), line, i);
  183.         }
  184.      }
  185.      /* Free last link */
  186.  
  187.      if ((*menuptr)->data->prev == NULL) {
  188.         free((*menuptr)->data);
  189.         (*menuptr)->data = NULL;
  190.      } else {
  191.         (*menuptr)->data = (*menuptr)->data->prev;
  192.         free((*menuptr)->data->next);
  193.         (*menuptr)->data->next = NULL;
  194.  
  195.         /* rewind linked list */
  196.  
  197.         while ((*menuptr)->data->prev != NULL)
  198.            (*menuptr)->data = (*menuptr)->data->prev;
  199.      }
  200.  
  201.      /* Allocate another link */
  202.      (*menuptr)->next = (struct menu *)malloc(sizeof(struct menu));
  203.      (*menuptr)->next->prev = *menuptr;
  204.      *menuptr = (*menuptr)->next;
  205.      (*menuptr)->next = NULL;
  206.      (*menuptr)->data = NULL;
  207.       }
  208.    }
  209.  
  210.    /* Free last link */
  211.  
  212.    if ((*menuptr)->prev == NULL) {
  213.       free(*menuptr);
  214.       *menuptr = NULL;
  215.    } else {
  216.       *menuptr = (*menuptr)->prev;
  217.       free((*menuptr)->next);
  218.       (*menuptr)->next = NULL;
  219.  
  220.       /* rewind linked list */
  221.  
  222.       while ((*menuptr)->prev != NULL)
  223.      *menuptr = (*menuptr)->prev;
  224.    }
  225.  
  226.    /* free variables */
  227.    
  228.    free(word);
  229.    free(line);
  230.    
  231.    return(0);
  232. }
  233.  
  234. /* frees up allocated memory
  235. ** On entry:
  236. **    menuptr == linked menu list
  237. **    menufile == loaded menu file
  238. ** On Exit:
  239. **    nothing, DONT USE menuptr OR menufile without allocating them again
  240. */
  241.  
  242. void freemem(struct menu *menuptr, char *menufile) {
  243.    free(menufile);
  244.  
  245.    while (menuptr != NULL) {
  246.       struct menu *p;
  247.  
  248.       p = menuptr;
  249.       menuptr = menuptr->next;
  250.       while (p->data != NULL) {
  251.      struct menu_items *q;
  252.      
  253.      q = p->data;
  254.      p->data = p->data->next;
  255.      if (q->name != NULL)
  256.         free(q->name);
  257.      if (q->args != NULL)
  258.         free(q->args);
  259.      free(q);
  260.       }
  261.       free(p->name);
  262.       free(p);
  263.    }
  264. }
  265.